from applications.common.picture_search.recognition_util import RecognitionUtil
# from applications.common.hangingUpCore.operation.base_operation import BaseOperation
from applications.common.hangingUpCore.operation.achieve.click_operation import ClickOperation
from applications.common.hangingUpCore.operation.achieve.dbclick_operation import DbclickOperation


'''
    挂机执行逻辑(主要判断当前所处的步骤,并分发具体执行操作)
'''
class ExecutionLogic:
    def __init__(self):
        pass

    '''
        设置属性值
        opertionParam : 操作逻辑所需属性
    '''
    def setAttribute(self,opertionParam):
        ## 图片检测属性所有相关数据 ,菜单组, 任务(项目)组,检测图片（标志检测列表）,操作（操作列表）; 的关联id进行对应
        self.groupMenuList = opertionParam.get('groupMenuList') if 'groupMenuList' in opertionParam else [] 
        self.groupTaskList = opertionParam.get('groupTaskList') if 'groupTaskList' in opertionParam else []
        self.detectionList = opertionParam.get('detectionList') if 'detectionList' in opertionParam else []
        self.operationList = opertionParam.get('operationList') if 'operationList' in opertionParam else []

        ## 是否debug模式
        self.debugMode = opertionParam.get('debugMode') if 'debugMode' in opertionParam else False

        ## 给数据组按照sort由小到大进行排序
        self.groupMenuList.sort(key=lambda item : item.sort,reverse = False)

        # 维持一个 recognitionUtil 依赖 对象
        self.recognitionUtil = RecognitionUtil(dict())
        self.baseOperation = None
        self.operationDict = dict(
            click = ClickOperation(),
            dbclick = DbclickOperation()
        )

        ## 保存当前所处组的步骤信息
        self.stepGroupInfo = {
            'menuIndex' : -1, # 当前所处菜单组的步骤序号，初始为-1;
            'menuContent' : None,  # 当前所处菜单组的步骤的具体组信息;
            'taskList' : [], # 菜单所包含的任务列表
        }
        # 保存所处检测和操作信息
        self.stepCheckInfo = {
            'taskIndex' : -1, # 当前所处的 taskList任务组 的序号，初始为-1;
            'taskContent' : None,  # 当前所处的 taskList任务组 的详细信息

            'detectionIndex' : -1, # 当前检测到的图片序号
            'detectionResult' : None, # 识别结果信息
            'detectionList' : [],  # 任务所包含的 检测图片信息
            
            'operationList' : [],  # 检测图片所包含的 操作 信息 与检测图片序号对应 ,操作由优先级排序
        }
        # 保留系统执行状态
        self.stateInfo = {
            'runing' : False,  # 是否执行中，初始为False
            'menuEnd' : False,  # 菜单是否执行完毕 ,初始为False
            'taskEnd' : False,  # 当前任务是否执行完毕 ,初始为False
            'finish' : False, # 任务是否完全处理完毕,初始为False, 当menuEnd 与 TaskEnd 都为True时表示执行完毕
        }


    '''
        处理当前所处的任务组,并缓存当前任务组的数据
        执行进度变更
    '''
    def hanldeTaskGroup(self):
        # 执行进度进行变更
        if self.stepGroupInfo == -1 :
            # 如果为-1表示是第一次进入，对数据进行初始化
            # 判断数据是否为空，为空就直接进入执行完毕状态
            if len(self.groupMenuList) or len(self.groupTaskList) or len(self.detectionList) or len(self.operationList) : 
                self.stateInfo['menuEnd'] = True
                self.stateInfo['taskEnd'] = True
            else :
                # 设置 菜单组 和 任务组的 序号都初始化为0
                self.stepGroupInfo['menuIndex'] = 0 
                self.stepCheckInfo['taskIndex'] = 0
        else :     
            # 如果为非-1表示是并非第一次进入，进入下一阶段
            #判断当前是否应该继续执行下一个任务还是
            if self.stateInfo[' '] : 
                # 判断是否当前任务组执行完毕,如果执行完毕,则进入下一个菜单组进行执行;
                if len(self.stepCheckInfo['stepCheckInfo']) > self.stepCheckInfo['taskIndex']  + 1 :
                    self.stepCheckInfo['taskIndex'] =  self.stepCheckInfo['taskIndex'] + 1
                else : 
                    if len(self.groupMenuList) > self.stepGroupInfo['menuIndex']  + 1 :
                        self.stepGroupInfo['menuIndex'] =  self.stepGroupInfo['menuIndex'] + 1
                    else : 
                        self.stateInfo['menuEnd'] = True
            else :
                # 表示当前阶段还未执行完毕，跳过
                return

        
        if self.stateInfo['taskEnd'] and self.stateInfo['menuEnd'] :
            # 标志为已经执行结束的状态,并跳过后续任务
            self.stateInfo['finish'] = True
            return

        # 将 检测和操作信息 和 步骤信息 的内容进行重新填充
        self.stepGroupInfo['menuContent'] = self.groupMenuList[self.stepGroupInfo['menuIndex']]
        self.stepGroupInfo['taskList'] = filter(lambda item : item.parent_id == self.stepGroupInfo['menuContent'].id, self.groupTaskList)
        self.stepGroupInfo['taskList'].sort(key=lambda item : item.sort,reverse = False) #正序

        self.stepCheckInfo['taskContent'] = self.stepGroupInfo['taskList'][self.stepCheckInfo['taskIndex']]
        self.stepCheckInfo['detectionList'] = filter(lambda item : item.group_id == self.stepCheckInfo['taskContent'].id, self.detectionList)
        self.stepCheckInfo['detectionList'].sort(key=lambda item : item.priority_level,reverse = True) # 逆序
        self.stepCheckInfo['operationList'] = map(lambda item : item.operation_list, self.stepCheckInfo['detectionList'])
        self.stepCheckInfo['operationList'].sort(key=lambda item : item.operation_order,reverse = False) # 顺序

        # 检查数据是否合理,不合理则继续变更步骤
        if len(self.stepCheckInfo['detectionList']) <= 0 : 
            self.hanldeTaskGroup()
            return
            
        # 重置当前状态信息
        self.stateInfo['taskEnd'] 


    '''
        检查当前所处步骤
    '''
    def checkNowStep(self):
        indexFlag = 0
        # 遍历列表进行监测数据
        for index in range(len(self.stepCheckInfo['detectionList'])):
            detectionInfo = self.stepCheckInfo['detectionList'][index]
            
            # 设置待查询图片和源图片
            self.recognitionUtil.setAttribute(dict(
                queryImageUrl = detectionInfo.picture_url,
                MIN_MATCH_COUNT = detectionInfo.feature_point,
                debugMode =  self.debugMode
            ))
            self.recognitionUtil.setWayOriginImage('screenshot')
            # 执行,获取架监测识别结果
            self.stepCheckInfo['detectionResult'] = self.recognitionUtil.recognitionCoordinate()

            # 处理执行结果
            if self.stepCheckInfo['detectionResult']['flag'] :
                continue
            indexFlag = index
        
        # 判断检测结果是否合理，合理则
        if indexFlag < len(self.stepCheckInfo['detectionList']) - 1 :
            self.stepCheckInfo['detectionIndex'] = indexFlag
        else :
            # 检测完所有图片，都未检测到，标志为结束状态， 并且初始化检测详细数据；
            self.stateInfo['taskEnd'] = True
            self.stepCheckInfo['detectionResult'] = None
            self.stepCheckInfo['detectionIndex'] = -1
    
    
    '''
        执行当前步骤的操所有操作
    '''
    def executeOperation(self):
        for index in range(len(self.stepCheckInfo['operationList'])):
            operationInfo = self.stepCheckInfo['operationList'][index]
            self.baseOperation = self.operationDict[operationInfo.operation_type]
            self.setAttribute(
                baseParam=operationInfo,
                recognitionUtil=self.recognitionUtil,
                debugMode = self.debugMode
            )
            self.baseOperation.execute()
            pass
        pass
    
    '''
        执行流程
    '''
    def executeExecution(self):
        #如果处于运行状态，直接退出执行
        if self.stateInfo['runing'] == True :
            return 
        # 以防万一，当状态为执行完成状态时，也一样退出执行
        if self.stateInfo['finish'] == True : 
            return 
        # 将正在运行状态置为True
        self.stateInfo['runing'] = True


        #如果 任务执行完毕 , 则变更状态
        if self.stateInfo['taskEnd'] == True :
            self.hanldeTaskGroup()
            # 当状态为执行完成状态时，也一样退出执行
            if self.stateInfo['finish'] == True : 
                return 
        
        # 开始检测当前所处的状态
        self.checkNowStep()
        # 开始执行档期那所处的步骤操作
        self.executeOperation()


        #执行完毕将执行状态设置为 False
        self.stateInfo['runing'] = False